﻿using Naruto.Redis.Object;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Naruto.Redis.Interface
{
    /// <summary>
    /// redis 流操作
    /// 
    /// </summary>
    public interface IRedisStream : IRedisDependency
    {

        #region 异步

        /// <summary>
        /// 新增一条流数据
        /// </summary>
        /// <param name="key">存储的key</param>
        /// <param name="values">存储的值</param>
        /// <param name="messageId">消息id 不填写 默认生成</param>
        /// <returns></returns>
        Task<string> AddAsync(string key, IDictionary<string, byte[]> values, string messageId = default, CancellationToken cancellationToken = default);

        /// <summary>
        /// 删除流信息 根据消息id
        /// </summary>
        /// <param name="key">存储的key</param>
        /// <param name="messageIds">消息id信息</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> DeleteAsync(string key, string[] messageIds, CancellationToken cancellationToken = default);

        /// <summary>
        /// 确认消息
        /// </summary>
        /// <param name="key">存储的key</param>
        /// <param name="groupName">消费者组名</param>
        /// <param name="messageId">消息id</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> AckAsync(string key, string groupName, string messageId, CancellationToken cancellationToken = default);


        /// <summary>
        /// 创建消费者组
        /// </summary>
        /// <param name="key"></param>
        /// <param name="groupName">组名</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<bool> CreateConsumerGroupAsync(string key, string groupName, CancellationToken cancellationToken = default);

        /// <summary>
        /// 获取消费者组信息
        /// </summary>
        /// <param name="key"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<ConsumerGroupInfo[]> GetConsumerGroupInfoAsync(string key, CancellationToken cancellationToken = default);


        /// <summary>
        /// 从指定的组读取流数据
        /// </summary>
        /// <param name="streamPositions">流信息</param>
        /// <param name="groupName">消费者组名称</param>
        /// <param name="consumerName">消费者名称</param>
        /// <param name="cancellationToken">是否自动确认</param>
        /// <param name="countPerStream">每次读取的流的数据条数</param>
        /// <returns></returns>
        Task<RedisStream[]> StreamReadGroupAsync(StreamPosition[] streamPositions, string groupName, string consumerName, int? countPerStream = null, bool noAck = false, CancellationToken cancellationToken = default);

        #endregion

        #region 同步

        /// <summary>
        /// 新增一条流数据
        /// </summary>
        /// <param name="key">存储的key</param>
        /// <param name="values">存储的值</param>
        /// <param name="messageId">消息id 不填写 默认生成</param>
        /// <returns></returns>
        string Add(string key, IDictionary<string, byte[]> values, string messageId = default);


        /// <summary>
        /// 删除流信息 根据消息id
        /// </summary>
        /// <param name="key">存储的key</param>
        /// <param name="messageIds">消息id信息</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        bool Delete(string key, string[] messageIds);


        /// <summary>
        /// 确认消息
        /// </summary>
        /// <param name="key">存储的key</param>
        /// <param name="groupName">消费者组名</param>
        /// <param name="messageId">消息id</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        bool Ack(string key, string groupName, string messageId);


        /// <summary>
        /// 创建消费者组
        /// </summary>
        /// <param name="key"></param>
        /// <param name="groupName">组名</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        bool CreateConsumerGroup(string key, string groupName);

        /// <summary>
        /// 获取消费者组信息
        /// </summary>
        /// <param name="key"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        ConsumerGroupInfo[] GetConsumerGroupInfo(string key);

        /// <summary>
        /// 从指定的组读取流数据
        /// </summary>
        /// <param name="streamPositions">流信息</param>
        /// <param name="groupName">消费者组名称</param>
        /// <param name="consumerName">消费者名称</param>
        /// <param name="countPerStream">每次读取的流的数据条数</param>
        /// <returns></returns>
        RedisStream[] StreamReadGroup(StreamPosition[] streamPositions, string groupName, string consumerName, int? countPerStream = null, bool noAck = false);

        #endregion
    }
}
